#include <memory>
#include <vector>
#include <fstream>
#include "HttpServer.hpp"
#include "Util.hpp"

#define WEBROOT "./wwwroot"    // web根目录
#define HOMEPAGE "/index.html" // 默认首页

// 使用手册
void Usage(std::string proc)
{
    std::cout << "\nUsage: " << proc << " port\n"
              << std::endl;
}

// 业务函数
void HandlerHttpRequest(int sock)
{
    // 1.1、读取一个http请求
    char buffer[10240];
    ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (s > 0)
    {
        buffer[s] = 0;
        std::cout << buffer << "\n--------------------\n"
                  << std::endl;
    }
    // 1.2、提取想要访问的资源路径
    std::vector<std::string> vline;
    Util::cutString(buffer, "\n", &vline); // 提取每一行(静态成员可直接用类访问)
    std::vector<std::string> vblock;
    Util::cutString(vline[0], " ", &vblock); // 提取第一行：将其每个部分分开

    std::string filepath = vblock[1]; // 请求行：方法 url http版本号
    std::string aimpath = WEBROOT;    // 固定web根目录./wwwroot
    if (filepath == "/")              // 说明访问web根目录./wwwroot/index.html
        aimpath += HOMEPAGE;
    else
        aimpath += filepath; //./wwwroot下的其它子目录
    std::cout << aimpath << std::endl;

    // 1.3、打开待访问路径下的文件
    std::string content;
    std::ifstream in(aimpath);
    if (in.is_open()) // 若成功打开，读取文件内容
    {
        std::string line;
        while (std::getline(in, line))
            content += line;
        in.close();
    }

    // 2、返回一个http响应
    std::string httpresponse;
    if (content.empty())
    {
        httpresponse = "HTTP/1.1 302 Found\r\n"; // 状态行
        httpresponse += "Location: http://43.142.190.243:9090/b/b-1.html\r\n";//演示重定向到自己的网址
    }
    else
    {
        httpresponse = "HTTP/1.1 200 OK\r\n"; // 状态行
        httpresponse +=("Content-Type: text/html\r\n");// 报头：数据类型(text/html等) 
        httpresponse +=("Content-Length: " + std::to_string(content.size()) + "\r\n"); //报头：Body的长度
        httpresponse +=("Set-cookie: 这是一个cookie,用于验证测试\r\n");// 报头：Cookie，通常用于实现会话(session)的功能;
    }
    httpresponse += "\r\n";                   // 响应报头：此处暂时没有，故直接填\r\n
    httpresponse += content;                  // 正文
    send(sock, httpresponse.c_str(), httpresponse.size(), 0);
}

// 服务端启动： ./HttpServer port
int main(int argc, char **argv)
{
    // 命令行参数检查
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }

    // 创建服务器
    std::unique_ptr<HttpServer> server(new HttpServer(atoi(argv[1]), HandlerHttpRequest));
    // 启动服务器
    server->Start();

    return 0;
}
